<template>
	<el-drawer
	  v-model="dialog.visible"
	  :title="dialog.title"
	  append-to-body
	  @close="closeDialog"
	  :close-on-click-modal="false"
	  size="750"
	>
	<el-scrollbar>
		<el-form
			ref="formRef"
			:model="formData"
			:rules="formRules"
			label-width="180px"
		>
			
			<el-form-item label="输入字段名称" prop="inputFieldName">
				<el-input v-model="formData.inputFieldName" placeholder="请输入输入字段名称" />
			</el-form-item>
			
			<el-form-item label="输入字段标识" prop="inputFieldIdentifier" >
			  <el-input 
			    v-model="formData.inputFieldIdentifier" 
			    placeholder="请输入输入字段路径，例如: data.list[0].name" 
			  >
			    <template #append>
			      <el-tooltip content="支持多级路径，使用.分隔，数组使用[index]表示" placement="top">
			        <el-icon><QuestionFilled /></el-icon>
			      </el-tooltip>
			    </template>
			  </el-input>
			</el-form-item>
			
			<el-form-item label="输入字段类型" prop="inputFieldType" >
				<Dict v-model="formData.inputFieldType" code="field_type" style="width: 100%;" />
			</el-form-item>
			
			
			<el-form-item label="输入日期格式定义" prop="inputFieldDateFormatSrc" v-if="['dateString'].includes(formData.inputFieldType)">
				<el-radio-group v-model="formData.inputFieldDateFormatSrc" class="flex-container">
					<el-radio value="input">自定义</el-radio>
					<el-radio value="select">下拉选择日期格式</el-radio>
				</el-radio-group>
			</el-form-item>
			
			<el-form-item label="输入日期格式" prop="inputFieldDateFormat" v-if="['dateString'].includes(formData.inputFieldType)">
				<el-select
					v-model="formData.inputFieldDateFormat"
					placeholder="请选择输入日期格式"
					v-if="formData.inputFieldDateFormatSrc=='select'"
				>
					<el-option label="yyyy-MM-dd" value="yyyy-MM-dd" />
					<el-option label="yyyy-MM-dd HH:mm:ss" value="yyyy-MM-dd HH:mm:ss" />
					<el-option label="yyyy年MM月dd日" value="yyyy年MM月dd日" />
					<el-option label="yyyy年MM月dd日 HH时mm分ss秒" value="yyyy年MM月dd日 HH时mm分ss秒" />
					<el-option label="HH:mm:ss" value="HH:mm:ss" />
					<el-option label="HH时mm分ss秒" value="HH时mm分ss秒" />
					<el-option label="yyyy/MM/dd" value="yyyy/MM/dd" />
					<el-option label="yyyy/MM/dd HH:mm:ss" value="yyyy/MM/dd HH:mm:ss" />
					<el-option label="yyyyMMdd" value="yyyyMMdd" />
					<el-option label="yyyyMMddHHmmss" value="yyyyMMddHHmmss" />
				</el-select>
				<el-input v-model="formData.inputFieldDateFormat" placeholder="请输入日期格式" v-else />
			</el-form-item>
			
			<el-form-item label="输入输出字段名称相同" prop="sameFieldName">
				<el-radio-group v-model="formData.sameFieldName" @change="handleSameFieldNameChange">
				  <el-radio value="0">不同</el-radio>
				  <el-radio value="1">相同</el-radio>
				</el-radio-group>
			</el-form-item>
			
			<el-form-item label="输出字段名称" prop="outputFieldName">
				<el-input v-model="formData.outputFieldName" placeholder="请输入输出字段名称" :readonly="formData.sameFieldName=='1'" />
			</el-form-item>
			
			<el-form-item label="输入输出字段标识相同" prop="sameFieldIdentifier">
				<el-radio-group v-model="formData.sameFieldIdentifier" @change="handleSameFieldIdentifierChange">
				  <el-radio value="0">不同</el-radio>
				  <el-radio value="1">相同</el-radio>
				</el-radio-group>
			</el-form-item>
			
			<el-form-item label="输出字段标识" prop="outputFieldIdentifier" >
			  <el-input 
			    v-model="formData.outputFieldIdentifier" 
			    placeholder="请输入输出字段路径，例如: data.list[0].name" 
				:readonly="formData.sameFieldIdentifier=='1'"
			  >
			    <template #append>
			      <el-tooltip content="支持多级路径，使用.分隔，数组使用[index]表示" placement="top">
			        <el-icon><QuestionFilled /></el-icon>
			      </el-tooltip>
			    </template>
			  </el-input>
			</el-form-item>
			
			<el-form-item label="输出字段类型" prop="outputFieldType">
				<Dict v-model="formData.outputFieldType" code="field_type" style="width: 100%;" />
			</el-form-item>
			
			<el-form-item label="时序库存储类型" prop="outputValueStorageType"  v-if="showStorageTypeField==true">
				<el-radio-group v-model="formData.outputValueStorageType" >
					<el-radio value="field">字段</el-radio>
					<el-radio value="tag" >标签</el-radio>
				</el-radio-group>
			</el-form-item>
			 
			<el-form-item label="输出字段值来源" prop="outputValueFromInput"  >
				<el-radio-group v-model="formData.outputValueFromInput" @change="handleOutputValueFromInputChange">
					<el-radio value="input">输入</el-radio>
					<el-radio value="OLTP" >OLTP</el-radio>
					<el-radio value="redis" >缓存(Redis)</el-radio>
					<el-radio value="constant" >常量</el-radio>
					<el-radio value="uuid" >uuid</el-radio>
					<el-radio value="curSystemDate" v-if="['dateString','long','timestampString'].includes(formData.outputFieldType)">系统时间</el-radio>
				</el-radio-group>
			</el-form-item>
			
			<el-form-item label="输出字段值OLTP数据源" prop="outputValueDatasourceId" v-if="formData.outputValueFromInput=='OLTP'" >
				<el-select v-model="formData.outputValueDatasourceId" >
					<el-option
					  v-for="item in datasourceOptions"
					  :key="item.id"
					  :label="item.name"
					  :value="item.id"
					/>
				</el-select>
			</el-form-item>
			
			<el-form-item label="输出字段取值SQL" prop="outputValueSql" v-if="formData.outputValueFromInput=='OLTP'">
				<div style="display: flex;flex-direction: column;width: 100%;">
					<MonacoEditor
					  v-model="formData.outputValueSql"
					  :options="sqlEditorOptions"
					  language="sql"
					  style="height: 200px;"
					  @change="validateSQL"
					/>
					
					<div class="sql-tips">
					  <el-alert
						title="SQL编写提示"
						type="info"
						:closable="false"
					  >
						<template #default>
						  <p>1. SQL语句支持以SELECT、Delete、Update等</p>
						  <p>2. SQL必须包含参数标识字段: {{ formData.outputFieldIdentifier?.split('.').pop() }}</p>
						  <p>3. 查询结果的字段名必须与参数标识字段匹配</p>
						  <p>4. 如果输入字段为sql参数，编写sql示例:( field=${输入字段标识})</p>
						</template>
					  </el-alert>
					</div>
				</div>
			</el-form-item>
			
			<el-form-item label="输出字段取值缓存标识" prop="outputValueRedisKey" v-if="formData.outputValueFromInput=='redis'">
				<el-input v-model="formData.outputValueRedisKey" placeholder="请输入输出字段取值缓存标识" />
			</el-form-item>
			
			<el-form-item label="输出字段日期格式" prop="outputFieldFormat" v-if="['dateString'].includes(formData.outputFieldType)">
				<el-select
					v-model="formData.outputFieldFormat"
					placeholder="请选择输出日期格式"
				>
					<el-option label="yyyy-MM-dd" value="yyyy-MM-dd" />
					<el-option label="yyyy-MM-dd HH:mm:ss" value="yyyy-MM-dd HH:mm:ss" />
					<el-option label="yyyy年MM月dd日" value="yyyy年MM月dd日" />
					<el-option label="yyyy年MM月dd日 HH时mm分ss秒" value="yyyy年MM月dd日 HH时mm分ss秒" />
					<el-option label="HH:mm:ss" value="HH:mm:ss" />
					<el-option label="HH时mm分ss秒" value="HH时mm分ss秒" />
					<el-option label="yyyy/MM/dd" value="yyyy/MM/dd" />
					<el-option label="yyyy/MM/dd HH:mm:ss" value="yyyy/MM/dd HH:mm:ss" />
					<el-option label="yyyyMMdd" value="yyyyMMdd" />
					<el-option label="yyyyMMddHHmmss" value="yyyyMMddHHmmss" />
				</el-select>
			</el-form-item>
			
			<el-form-item label="输出字段保留小数位" prop="outputFieldDecimalPoint" v-if="['float','double'].includes(formData.outputFieldType)">
				<el-input-number v-model="formData.outputFieldDecimalPoint" placeholder="请输入字段保留小数位" :min="0" :max="32" />
			</el-form-item>
			
			<el-form-item label="输出字段默认值" prop="outputFieldDefaultValue">
				<el-select v-model="formData.outputFieldDefaultValue" placeholder="请选择输出字段默认值" v-if="formData.outputFieldType=='boolean'">
				  <el-option label="true" :value="true" />
				  <el-option label="false" :value="false" />
				</el-select>
				<el-input-number v-model="formData.outputFieldDefaultValue" :min="0" v-else-if="formData.outputFieldType=='int'" placeholder="请输入输出字段默认值"/>
				<el-input v-model="formData.outputFieldDefaultValue" placeholder="请输入输出字段默认值" v-else />
			</el-form-item>
			
		</el-form>
	</el-scrollbar>
	
		<template #footer>
		  <div class="dialog-footer">
			<el-button type="primary" @click="submitForm" :loading="loading">确 定</el-button>
			<el-button @click="closeDialog" :loading="loading">取 消</el-button>
		  </div>
		</template>
	</el-drawer>
</template>

<script lang="ts" setup>
	import DatasourceAPI from "@/api/biz/datasource";
	import { ref } from "vue";
	import type {FormRules } from 'element-plus'
	import { ElMessage } from "element-plus";
	import { reactive } from "vue";
	import { onMounted } from "vue";
	import MonacoEditor from '@/components/MonacoEditor/index.vue'
	// import * as monaco from 'monaco-editor';
	// import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
	// import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
	// import sqlWorker from 'monaco-editor/esm/vs/language/sql/sql.worker?worker';
	// import 'monaco-editor/esm/vs/basic-languages/sql/sql.contribution';
	
	const validateSQL = (_rule: any, value: string | undefined, callback: any): void => {
	  if ((!value || value.trim() === '') && formData.value.outputValueFromInput === 'OLTP') {
	    callback(new Error('请输入SQL语句'));
	    return;
	  }
	  
	  if (value && formData.value.outputValueFromInput === 'OLTP') {
	    // 检查是否包含参数标识字段
	    const identifier = formData.value.outputFieldIdentifier;
	    const columnName = identifier.split('.').pop(); // 获取最后一段作为字段名
	    
	    // SQL 必须以 SELECT 开头
	    // if (!value.trim().toLowerCase().startsWith('select')) {
	    //   callback(new Error('SQL语句必须以SELECT开头'));
	    //   return;
	    // }
	    
	    // 检查是否包含参数标识字段
	    const hasIdentifier = value.toLowerCase().includes(columnName.toLowerCase());
	    if (!hasIdentifier) {
	      callback(new Error(`SQL语句必须包含参数标识字段: ${columnName}`));
	      return;
	    }
	  }
	  callback();
	};
	
	const emit = defineEmits(['success', 'closed']);
	const loading = ref(false);
	const dialog = ref({
		visible:false,
		title:'',
	});
	const rowIndex = ref<number>(1);
	const formRef=ref();
	const formRules=reactive<FormRules>({
		inputFieldName: [
			{ required: true, message: "请输入输入字段名", trigger: "blur" }
		],
		inputFieldIdentifier: [
			{ required: true, message: "请输入输入字段标识", trigger: "blur" }
		],
		inputFieldType: [
			{ required: true, message: "请选择输入字段类型", trigger: "change" }
		],
		inputFieldFormat: [
			{ required: true, message: "请选择输入字段值格式", trigger: "change" }
		],
		inputFieldDateFormatSrc: [
			{ required: true, message: "请选择输入字段日期定义方式", trigger: "change" }
		],
		inputFieldDateFormat: [
			{ required: true, message: "请选择或输入输入字段日期定格式", trigger: "change" }
		],
		sameFieldName: [
			{ required: true, message: "请选择是否字段名相同", trigger: "change" }
		],
		outputFieldName: [
			{ required: true, message: "请输入输出字段名", trigger: "blur" },
			{ min: 2, max: 50, message: "长度在 2 到 50 个字符", trigger: "blur" }
		],
		sameFieldIdentifier: [
			{ required: true, message: "请选择是否字段标识相同", trigger: "change" }
		],
		outputFieldIdentifier: [
			{ required: true, message: "请输入输出字段标识", trigger: "blur" },
			{ pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/, message: "标识符必须以字母开头，只能包含字母、数字和下划线", trigger: "blur" }
		],
		outputFieldType: [
			{ required: true, message: "请选择输出字段类型", trigger: "change" }
		],
		outputFieldFormat: [
			{ required: true, message: "请选择输出字段格式", trigger: "change" }
		],
		outputFieldDecimalPoint: [
			{ required: true, message: "请输入输出字段保留小数位", trigger: "change" }
		],
		outputValueFromInput: [
			{ required: true, message: "请选择输出取值输入", trigger: "change" }
		],
		outputValueDatasourceId: [
			{ required: true, message: "请选择输出字段取值数据源", trigger: "change" }
		],
		outputValueSql: [
			{ validator: validateSQL, trigger: 'blur' }
		],
		outputValueRedisKey: [
			{ required: true, message: "请输入输出字段取值缓存标识", trigger: "change" }
		],
		outputValueStorageType: [
			{ required: true, message: "请选择存储类型", trigger: "change" }
		],
	});
	
	const sqlEditorOptions = {
	  theme: 'vs-dark',
	  language: 'sql',
	  automaticLayout: true,
	  minimap: { enabled: false },
	  lineNumbers: 'on',
	  folding: true,
	  wordWrap: 'on',
	  fontSize: 14,
	  tabSize: 2,
	  formatOnPaste: true,
	  formatOnType: true,
	  suggestOnTriggerCharacters: true,
	  quickSuggestions: true,
	};
	
	//数据源
	const formData=ref<any>({
	});
	
	//监听输入输出字段名称是否一致
	const handleSameFieldNameChange=()=>{
		if(formData.value.sameFieldName=='1'){
			formData.value.outputFieldName=formData.value.inputFieldName;
		}
	}
	
	const handleSameFieldIdentifierChange=()=>{
		if(formData.value.sameFieldIdentifier=='1'){
			formData.value.outputFieldIdentifier=formData.value.inputFieldIdentifier;
		}
	}
	
	const handleOutputValueFromInputChange=()=>{
		if(formData.value.outputValueFromInput=='constant'){
			//handleOutputFieldDefaultValueRequiredChange();
			formRules["outputFieldDefaultValue"]=[
				{ required: true, message: "默认值必填.", trigger: "change" }
			]
		}else{
			delete formRules?.outputFieldDefaultValue
		}
	}
	
	const handleOutputFieldDefaultValueRequiredChange=()=>{
		if(formData.value.required=='1'){
			formRules["outputFieldDefaultValue"]=[
				{ required: true, message: "默认值必填.", trigger: "change" }
			]
		}else{
			delete formRules?.outputFieldDefaultValue
		}
	}
	
	//数据源下拉框
	const datasourceOptions=ref<any>([]);
	
	const getOLTPDatasources= async ()=>{
		try {
			const data = await DatasourceAPI.options({});
			datasourceOptions.value = data.map((item:any) => ({
				id: item.id,
				name: item.name
			}));
		} catch (error:any) {
			console.error(error)
			ElMessage.error('获取OLTP下拉数据失败');
		}
	}
	
	const showStorageTypeField=ref<boolean>();
	async function openDialog(index: number,_row?: any, type?: string,storageType?:boolean) {
		getOLTPDatasources();
		if('add'==type){
			rowIndex.value=index;
			dialog.value.visible=true;
			dialog.value.title='新增字段';
			showStorageTypeField.value=storageType||false;
		}else{
			rowIndex.value=index;
			dialog.value.visible=true;
			dialog.value.title='编辑字段';
			showStorageTypeField.value=storageType||false;
			formData.value=JSON.parse(JSON.stringify(_row))
		}
	}
	
	const submitForm=()=>{
		formRef.value.validate((isValid: boolean) => {
			if (isValid) {
				loading.value = true;
				emit('success', rowIndex.value, JSON.parse(JSON.stringify(formData.value)));
				loading.value = false;
				closeDialog();
			}
		});
	}
	
	const closeDialog=()=>{
		dialog.value.visible=false;
		dialog.value.title="";
		emit('closed')
		resetForm();
	}
	
	/**
	 * 重置表单
	 */
	function resetForm() {
		formRef.value.resetFields();
		formRef.value.clearValidate();
		formData.value={};
	}	
	
	defineExpose({
	  openDialog,closeDialog
	});
	
	onMounted(() => {
	});
</script>

<style scoped>
	.step-content{
		background-color: aliceblue;
		margin-top: 8px;
		padding: 8px;
		padding-top: 16px;
	}
</style>